package by.brest.bspc.repository.converters;

import by.brest.bspc.domain.Grade;
import by.brest.bspc.domain.Specialty;
import by.brest.bspc.domain.Student;
import com.mongodb.DBObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.convert.converter.Converter;

import java.util.LinkedList;
import java.util.List;

import static by.brest.bspc.repository.Constants.CLASS_NUMBER;
import static by.brest.bspc.repository.Constants.DIRESPECT;
import static by.brest.bspc.repository.Constants.DISCIPLINE_NAME;
import static by.brest.bspc.repository.Constants.FACULTY;
import static by.brest.bspc.repository.Constants.GRADE_LIST;
import static by.brest.bspc.repository.Constants.GRADE_TYPE;
import static by.brest.bspc.repository.Constants.GROUP_NAME;
import static by.brest.bspc.repository.Constants.ID;
import static by.brest.bspc.repository.Constants.MARK;
import static by.brest.bspc.repository.Constants.RESPECT;
import static by.brest.bspc.repository.Constants.SEMESTER_NUMBER;
import static by.brest.bspc.repository.Constants.SPECIALTY;
import static by.brest.bspc.repository.Constants.SPECIALTY_CODE;
import static by.brest.bspc.repository.Constants.SPECIALTY_NAME;
import static by.brest.bspc.repository.Constants.STATUS;
import static by.brest.bspc.repository.Constants.STUDENT_NAME;
import static by.brest.bspc.repository.Constants.STUDY;
import static by.brest.bspc.repository.Constants.TEACHER_NAME;

/**
 * This class converts <code>DBObject</code> to <code>Student</code>.
 *
 * @date: 06.09.13 19:37
 * @author: Natallia
 */
public class StudentReadConverter implements Converter<DBObject, Student> {
    private static final Logger LOG = LoggerFactory.getLogger(StudentReadConverter.class);

    /**
     * Converts <code>DBObject</code> to <code>Student</code>.
     *
     * @param studentDBObject <code>DBObject</code>, that need to convert to <code>Student</code>.
     * @return <code>Student</code>.
     */
    @Override
    public Student convert(DBObject studentDBObject) {
        LOG.debug(">> studentDBObject, that need to convert: " + studentDBObject);

        Student student = new Student();

        if (studentDBObject == null) {
            LOG.debug(">> studentDBObject is null.");
        } else {
            student.setId(studentDBObject.get(ID).toString());
            student.setName((String) studentDBObject.get(STUDENT_NAME));
            student.setStudy((String) studentDBObject.get(STUDY));
            student.setFaculty((String) studentDBObject.get(FACULTY));

            DBObject specialtyDBObject = (DBObject) studentDBObject.get(SPECIALTY);

            Specialty specialty = new Specialty();
            if (specialtyDBObject == null) {

                LOG.debug(">> specialtyDBObject is null.");

            } else {
                specialty.setName((String) specialtyDBObject.get(SPECIALTY_NAME));
                specialty.setCode((String) specialtyDBObject.get(SPECIALTY_CODE));
            }

            student.setSpecialty(specialty);
            if (studentDBObject.get(CLASS_NUMBER) == null) {
                LOG.debug(">> studentDBObject.get(CLASS_NUMBER) is null.");
            } else {
                student.setClassNumber((int) studentDBObject.get(CLASS_NUMBER));
            }

            student.setGroupName((String) studentDBObject.get(GROUP_NAME));

            List<DBObject> gradeListDBObject = (List<DBObject>) studentDBObject.get(GRADE_LIST);

            LOG.debug(">> Returned gradeListDBObject: " + gradeListDBObject);

            List<Grade> gradeList = new LinkedList<>();
            if (gradeListDBObject == null) {

                LOG.debug(">> gradeListDBObject is null.");

            } else {
                for (DBObject gradeDBObject : gradeListDBObject) {
                    Grade grade = new Grade();
                    grade.setGradeType((String) gradeDBObject.get(GRADE_TYPE));
                    if (gradeDBObject.get(SEMESTER_NUMBER) == null) {
                        LOG.debug(">> gradeDBObject.get(SEMESTER_NUMBER) is null.");
                    } else {
                        grade.setSemesterNumber((int) gradeDBObject.get(SEMESTER_NUMBER));
                    }
                    grade.setDisciplineName((String) gradeDBObject.get(DISCIPLINE_NAME));
                    grade.setTeacherName((String) gradeDBObject.get(TEACHER_NAME));
                    if (gradeDBObject.get(MARK) == null) {
                        LOG.debug(">> gradeDBObject.get(MARK) is null.");
                    } else {
                        grade.setMark((int) gradeDBObject.get(MARK));
                    }
                    if (gradeDBObject.get(RESPECT) == null) {
                        LOG.debug(">> gradeDBObject.get(RESPECT) is null.");
                    } else {
                        grade.setRespect((int) gradeDBObject.get(RESPECT));
                    }
                    if (gradeDBObject.get(DIRESPECT) == null) {
                        LOG.debug(">> gradeDBObject.get(DIRESPECT) is null.");
                    } else {
                        grade.setDirespect((int) gradeDBObject.get(DIRESPECT));
                    }

                    LOG.debug(">> Converted grade: " + grade);

                    gradeList.add(grade);
                }
            }

            LOG.debug(">> Converted gradeList: " + gradeList);
            student.setGradeList(gradeList);
            student.setStatus((String) studentDBObject.get(STATUS));

            LOG.debug(">> Converted student: " + student);
        }

        return student;
    }
}
